home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Utilities / DVIM72-Mac 1.9.6 / source / SPECIAL.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-09-14  |  5.6 KB  |  220 lines  |  [TEXT/R*ch]

  1. /* -*-C-*- special.h */
  2. /*-->special*/
  3. /**********************************************************************/
  4. /****************************** special *******************************/
  5. /**********************************************************************/
  6.  
  7. /*
  8.     In DVIM72-Mac, we implement \special to include PICT files.
  9.     I use as an outline the procedure in Inside Macintosh, V-88.
  10. */
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14. #include <ctype.h>
  15. #include "dvihead.h"
  16. #include "commands.h"
  17. #include "gendefs.h"
  18. #include "gblprocs.h"
  19. #include "m72.h"
  20. #include "egblvars.h"
  21. #include "mac-specific.h"
  22. #include "Scale_rect.h"
  23. #include "Parse_special.h"
  24.  
  25.  
  26.  
  27. /* --------- Globals ----------- */
  28. short        g_PICT_refnum;
  29. Str255    g_PICT_filename;
  30.  
  31. /* ---------- Prototypes -------- */
  32. void Handle_io_error( OSErr err, Str255 fn );
  33. pascal void Get_PICT_data( Ptr data_ptr, int byte_count );
  34.  
  35. #define HEADER_SIZE        512
  36. #define HEADER_TOO_SMALL    5000
  37. #define OUT_OF_MEMORY        5001
  38. #define CANT_READ_PICT        5002
  39. #define SCREEN_DPI            72
  40.  
  41. /* ---------------------- special ---------------------------------- */
  42. void
  43. special(s)            /* process TeX \special{} string in s[] */
  44. register char *s;
  45. {
  46.     GrafPtr save_port;
  47.     Rect    dest_rect, print_dest, preview_dest;
  48.     int        i;
  49.     OSErr    err;
  50.     FInfo    finder_info;
  51.     long    pict_size;
  52.     char    pict_header[HEADER_SIZE];
  53.     PicHandle    the_pict;
  54.     float    hscale, vscale;
  55.     short    keytype;
  56.  
  57.     for (i = 0; i < strlen(s); i++)
  58.         tolower( s[i] );
  59.     
  60.     s = Get_keyword( s, &keytype );
  61.     if (keytype != sp_pict)
  62.         return;                    /* Not our type of \special */
  63.     s = Get_filename( s, g_PICT_filename );
  64.     err = GetFInfo( g_PICT_filename, 0, &finder_info );
  65.     if (err != noErr)
  66.     {
  67.         Handle_io_error( err, g_PICT_filename );
  68.         return;
  69.     }
  70.     else if (finder_info.fdType != 'PICT')
  71.         return;                    /* File is not a PICT */
  72.     err = HOpen( 0, NIL, g_PICT_filename, fsRdPerm, &g_PICT_refnum );
  73.     if (err != noErr)
  74.     {
  75.         Handle_io_error( err, g_PICT_filename );
  76.         return;
  77.     }
  78.  
  79.     /* Skip the header */
  80.     err = SetFPos( g_PICT_refnum, fsFromStart, HEADER_SIZE );
  81.     if (err != noErr)
  82.     {
  83.         Handle_io_error( err, g_PICT_filename );
  84.         (void) FSClose( g_PICT_refnum );
  85.         return;
  86.     }
  87.     
  88.     /* Now We're just going to read enough to get the picture frame. */
  89.     the_pict = (PicHandle) NewHandle( sizeof(Picture) );
  90.     if (the_pict == nil)
  91.     {
  92.         Handle_io_error( OUT_OF_MEMORY, g_PICT_filename );
  93.         (void) FSClose( g_PICT_refnum );
  94.         return;
  95.     }
  96.     HLock( (Handle)the_pict );
  97.     pict_size = sizeof(Picture);
  98.     err = FSRead( g_PICT_refnum, &pict_size, *the_pict );
  99.     if (err != noErr)
  100.     {
  101.         Handle_io_error( err, g_PICT_filename );
  102.         (void) FSClose( g_PICT_refnum );
  103.         HUnlock( (Handle)the_pict );
  104.         DisposHandle( (Handle)the_pict );
  105.         return;
  106.     }
  107.     
  108.     /* Scale and place the picture. */
  109.     dest_rect = (**the_pict).picFrame;
  110.     /*
  111.         Make the bottom left corner be the origin. Then the values
  112.         of right and top will be the width and height, in points.
  113.     */
  114.     OffsetRect( &dest_rect, -dest_rect.left, -dest_rect.bottom );
  115.  
  116.     Get_scales( s, &hscale, &vscale, -dest_rect.top, dest_rect.right );
  117.     
  118.     dest_rect.right = (short)((float)dest_rect.right * (float)g_dpi
  119.         * hscale / SCREEN_DPI + 0.5);
  120.     dest_rect.top = (short)((float)dest_rect.top * (float)g_dpi
  121.         * vscale / SCREEN_DPI + 0.5);
  122.     OffsetRect( &dest_rect, hh, vv );
  123.  
  124.     GetPort( &save_port );
  125.     if (g_draw_offscreen)
  126.     {
  127.         SetPort( &g_offscreen_GrafPort );
  128.         DrawPicture( the_pict, &dest_rect );
  129.     }
  130.     else
  131.     {
  132.         Scale_rect( &dest_rect, &print_dest, &preview_dest );
  133.         /*
  134.             Now we're ready to draw a QuickDraw \special
  135.         */
  136.         SetPort( (GrafPtr)g_print_port_p );
  137.         DrawPicture( the_pict, &print_dest );
  138.         
  139.         if (g_preview)
  140.         {
  141.             (void) SetFPos( g_PICT_refnum, fsFromStart, HEADER_SIZE + pict_size );
  142.             SetPort( g_page_window );
  143.             DrawPicture( the_pict, &preview_dest );
  144.         }
  145.     }
  146.     /*
  147.         Put things back to normal.
  148.     */
  149.     SetPort( save_port );
  150.     HUnlock( (Handle)the_pict );
  151.     DisposHandle( (Handle)the_pict );
  152.     
  153.     (void) FSClose( g_PICT_refnum );
  154. }
  155.  
  156. /* -------------------------- Get_PICT_data -------------------------- */
  157. pascal void Get_PICT_data( Ptr data_ptr, int byte_count )
  158. {
  159.     long    long_count;
  160.     OSErr    err;
  161.     
  162.     long_count = byte_count;
  163.     err = FSRead( g_PICT_refnum, &long_count, data_ptr );
  164.     if (err != noErr)
  165.         Handle_io_error( err, g_PICT_filename );
  166. }
  167.  
  168. /* ------------------------ Handle_io_error -------------------------- */
  169. void Handle_io_error( OSErr err, Str255 fn )
  170. {
  171.     char    message[256];
  172.     
  173.     switch (err)
  174.     {
  175.         case bdNamErr:
  176.             (void)sprintf(message, "Bad file name error on '%#s'.", fn );
  177.             break;
  178.         case extFSErr:
  179.             (void)sprintf(message, "External file system error on '%#s'.", fn );
  180.             break;
  181.         case fnfErr:
  182.             (void)sprintf(message, "File not found error on '%#s'.", fn );
  183.             break;
  184.         case ioErr:
  185.             (void)sprintf(message, "I/O error on '%#s'.", fn );
  186.             break;
  187.         case nsvErr:
  188.             (void)sprintf(message, "No such volume error on '%#s'.", fn );
  189.             break;
  190.         case paramErr:
  191.             (void)sprintf(message, "Negative count error on '%#s'.", fn );
  192.             break;
  193.         case eofErr:
  194.             (void)sprintf(message, "End of file error on '%#s'.", fn );
  195.             break;
  196.         case fnOpnErr:
  197.             (void)sprintf(message, "File not open error on '%#s'.", fn );
  198.             break;
  199.         case rfNumErr:
  200.             (void)sprintf(message, "Bad reference number error on '%#s'.", fn );
  201.             break;
  202.         case opWrErr:
  203.             (void)sprintf(message, "File '%#s' already open.", fn );
  204.             break;
  205.         case tmfoErr:
  206.             (void)sprintf(message, "Too many files open error on '%#s'.", fn );
  207.             break;
  208.         case OUT_OF_MEMORY:
  209.             (void)sprintf(message, "Out of memory reading '%#s'.", fn );
  210.             break;
  211.         case HEADER_TOO_SMALL:
  212.             (void)sprintf(message, "Header size error on '%#s'.", fn );
  213.             break;
  214.         default:
  215.             (void)sprintf(message, "Miscellaneous error on '%#s'.", fn );
  216.             break;
  217.     }
  218.     Show_error( message );
  219. }
  220.